// extern crate pretty_env_logger;
#[macro_use]
extern crate log;

use std::iter::repeat_with;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};

use anyhow::Result;
use rand::distributions::Uniform;
use rand::prelude::*;
use smol::Timer;

const ALPHA_NUMBER: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

fn main() -> Result<()> {
    pretty_env_logger::init();

    let date = chrono::Local::now().format("%F");
    info!("{}", date);

    let mut a = rand::thread_rng();
    let b = Uniform::new(0, 1000000);
    let mut c = b.sample_iter(&mut a);
    info!("Hello, world! {}", format!("{:?}", Instant::now()));
    info!("Hello, world! {}", format!("{:#?}", Instant::now()));
    info!("Hello, world! {:?}", Instant::now().elapsed().as_nanos());
    info!("{}{:02}{:06}", now()?, 3, c.next().unwrap());
    info!("{}{:02}{:06}", now()?, 3, c.next().unwrap());
    info!("{}{:02}{:06}", now()?, 3, c.next().unwrap());
    info!(
        "SD001{}{:02}{:06}",
        chrono::Local::now().timestamp_nanos(),
        3,
        c.next().unwrap()
    );
    info!("{}{:02}{:06}", naive_now()?, 3, c.next().unwrap());

    let temp = chrono::Local::now().naive_local();
    debug!("{}|{}", temp.timestamp(), temp.timestamp_nanos());
    let naive_time = chrono::naive::NaiveDateTime::from_timestamp(
        temp.timestamp(),
        temp.timestamp_subsec_nanos(),
    );
    info!("{}", naive_time);
    let rng = fastrand::Rng::new();
    info!(
        "SD001{}{:02}{:06}",
        naive_time.timestamp_nanos(),
        3,
        random_alpha_number(&rng, 6)
    );

    smol::block_on(Timer::after(Duration::from_secs(2)));
    let duration = naive_time.signed_duration_since(chrono::Local::now().naive_local());
    info!("Duration :{}", duration.num_seconds());
    smol::block_on(Timer::after(Duration::from_secs(
        duration.num_seconds().abs() as u64,
    )));
    info!("block over");

    Ok(())
}

fn now() -> Result<String> {
    Ok(format!(
        "SD001{}",
        SystemTime::now().duration_since(UNIX_EPOCH)?.as_nanos(),
    ))
}

fn naive_now() -> Result<String> {
    let now = chrono::Local::now();
    Ok(format!("SD001{}", now.timestamp_nanos()))
}

fn random_alpha_number(rng: &fastrand::Rng, len: usize) -> String {
    repeat_with(|| ALPHA_NUMBER[rng.usize(..ALPHA_NUMBER.len())] as char)
        .take(len)
        .collect()
}
